1 package org.apache.maven.surefire.junit;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.lang.reflect.InvocationHandler;
23 import java.lang.reflect.InvocationTargetException;
24 import java.lang.reflect.Method;
25 import java.util.HashSet;
26 import java.util.Set;
27 import org.apache.maven.surefire.report.LegacyPojoStackTraceWriter;
28 import org.apache.maven.surefire.report.ReportEntry;
29 import org.apache.maven.surefire.report.RunListener;
30 import org.apache.maven.surefire.report.SimpleReportEntry;
31
32
33
34
35
36 public class TestListenerInvocationHandler
37 implements InvocationHandler
38 {
39
40 private static final String START_TEST = "startTest";
41
42 private static final String ADD_FAILURE = "addFailure";
43
44 private static final String ADD_ERROR = "addError";
45
46 private static final String END_TEST = "endTest";
47
48 private final Set<FailedTest> failedTestsSet = new HashSet<FailedTest>();
49
50 private RunListener reporter;
51
52 private static final Class[] EMPTY_CLASS_ARRAY = new Class[]{ };
53
54 private static final String[] EMPTY_STRING_ARRAY = new String[]{ };
55
56 private static class FailedTest
57 {
58 private Object testThatFailed;
59
60 private Thread threadOnWhichTestFailed;
61
62 FailedTest( Object testThatFailed, Thread threadOnWhichTestFailed )
63 {
64 if ( testThatFailed == null )
65 {
66 throw new NullPointerException( "testThatFailed is null" );
67 }
68
69 if ( threadOnWhichTestFailed == null )
70 {
71 throw new NullPointerException( "threadOnWhichTestFailed is null" );
72 }
73
74 this.testThatFailed = testThatFailed;
75
76 this.threadOnWhichTestFailed = threadOnWhichTestFailed;
77 }
78
79 public boolean equals( Object obj )
80 {
81 boolean retVal = true;
82
83 if ( obj == null || getClass() != obj.getClass() )
84 {
85 retVal = false;
86 }
87 else
88 {
89 FailedTest ft = (FailedTest) obj;
90
91 if ( ft.testThatFailed != testThatFailed )
92 {
93 retVal = false;
94 }
95 else if ( !ft.threadOnWhichTestFailed.equals( threadOnWhichTestFailed ) )
96 {
97 retVal = false;
98 }
99 }
100
101 return retVal;
102 }
103
104 public int hashCode()
105 {
106 return threadOnWhichTestFailed.hashCode();
107 }
108 }
109
110 public TestListenerInvocationHandler( RunListener reporter )
111 {
112 if ( reporter == null )
113 {
114 throw new NullPointerException( "reporter is null" );
115 }
116
117 this.reporter = reporter;
118 }
119
120 public Object invoke( Object proxy, Method method, Object[] args )
121 throws Throwable
122 {
123 String methodName = method.getName();
124
125 if ( methodName.equals( START_TEST ) )
126 {
127 handleStartTest( args );
128 }
129 else if ( methodName.equals( ADD_ERROR ) )
130 {
131 handleAddError( args );
132 }
133 else if ( methodName.equals( ADD_FAILURE ) )
134 {
135 handleAddFailure( args );
136 }
137 else if ( methodName.equals( END_TEST ) )
138 {
139 handleEndTest( args );
140 }
141
142 return null;
143 }
144
145
146 public void handleStartTest( Object[] args )
147 {
148 ReportEntry report = new SimpleReportEntry( args[0].getClass().getName(), args[0].toString() );
149
150 reporter.testStarting( report );
151 }
152
153
154 private void handleAddError( Object[] args )
155 throws IllegalAccessException, InvocationTargetException
156 {
157 ReportEntry report = SimpleReportEntry.withException( args[0].getClass().getName(), args[0].toString(),
158 getStackTraceWriter( args ) );
159
160 reporter.testError( report );
161
162 failedTestsSet.add( new FailedTest( args[0], Thread.currentThread() ) );
163 }
164
165 private LegacyPojoStackTraceWriter getStackTraceWriter( Object[] args )
166 throws IllegalAccessException, InvocationTargetException
167 {
168 String testName;
169
170 try
171 {
172 Method m = args[0].getClass().getMethod( "getName", EMPTY_CLASS_ARRAY );
173 testName = (String) m.invoke( args[0], EMPTY_STRING_ARRAY );
174 }
175 catch ( NoSuchMethodException e )
176 {
177 testName = "UNKNOWN";
178 }
179
180 return new LegacyPojoStackTraceWriter( args[0].getClass().getName(), testName, (Throwable) args[1] );
181 }
182
183 private void handleAddFailure( Object[] args )
184 throws IllegalAccessException, InvocationTargetException
185 {
186 ReportEntry report = SimpleReportEntry.withException( args[0].getClass().getName(), args[0].toString(),
187 getStackTraceWriter( args ) );
188
189 reporter.testFailed( report );
190
191 failedTestsSet.add( new FailedTest( args[0], Thread.currentThread() ) );
192 }
193
194 private void handleEndTest( Object[] args )
195 {
196 boolean testHadFailed = failedTestsSet.remove( new FailedTest( args[0], Thread.currentThread() ) );
197
198 if ( !testHadFailed )
199 {
200 ReportEntry report = new SimpleReportEntry( args[0].getClass().getName(), args[0].toString() );
201
202 reporter.testSucceeded( report );
203 }
204 }
205 }